<script setup>
import { onMounted, ref } from 'vue'
import { Peer } from 'peerjs'
const localVideo = ref(null)
const remoteVideo = ref(null)
const recordVideo = ref(null)
let localStream = null
let remoteStream = null
const remotePeerId = ref('')
const peerId = ref('')
const message = ref('')
const messageList = ref([])
const peer = new Peer({
  host: '192.168.137.130',
  port: 9000,
  path: '/peerjs',
  config: {},
  secure: false
})
// const peer = new Peer()
peer.on('open', (id) => {
  peerId.value = id
  console.log('peer已成功连接' + id)
})

peer.on('error', (id) => {
  console.log('peer连接失败' + id)
})

/**
 * 监听peer消息
 */
peer.on('connection', (connection) => {
  console.log('Incoming connection from ' + connection.peer)
  // 监听接收到的消息
  connection.on('data', (data) => {
    console.log('Received message:', data)
  })
})
onMounted(async () => {
  const stream = await navigator.mediaDevices.getUserMedia({
    video: { width: 200, height: 150 },
    audio: true
  })
  localStream = stream
  localVideo.value.srcObject = localStream
})

/**
 * 发起呼叫，传递远端的peerid和本地视频流
 * 发起数据连接通道
 */
let dataConnection = null
let call = null
const sendCall = () => {
  // 发起音视频连接
  call = peer.call(remotePeerId.value, localStream)
  call.on('stream', (stream) => {
    remoteStream = stream
    remoteVideo.value.srcObject = remoteStream
  })
  call.on('close', () => {
    console.log('呼叫关闭')
    remoteStream = null
  })
  // 发起数据连接
  dataConnection = peer.connect(remotePeerId.value)
  dataConnection.on('open', () => {
    console.log('远端通道连接成功-111')
  })
  dataConnection.on('data', (data) => {
    sendMessage('remote', data)
  })
}

/**
 * 发送或显示消息列表
 * @param { string } type 消息类型
 * @param { string } message 消息数据
 */

const sendMessage = (type, data) => {
  messageList.value.push({
    message: type === 'self' ? message.value : data,
    type,
    time: new Date().getTime()
  })
  if (type === 'self') {
    dataConnection.send(message.value)
    message.value = ''
  }
}

/**
 * 断开连接
 */
const closeCall = () => {
  call.close()
}

/**
 * 开启录制功能
 */
let chunks = []
let mediaRecorder = null
const startRecordVideo = async () => {
  const stream = await navigator.mediaDevices.getUserMedia({
    video: true,
    audio: true
  })
  recordVideo.value.srcObject = stream
  mediaRecorder = new MediaRecorder(stream)
  mediaRecorder.ondataavailable = (event) => {
    console.log('录制监听')
    if (event.data.size > 0) {
      console.log(event.data)
      chunks.push(event.data)
    }
  }
  mediaRecorder.onstop = () => {
    var recordedBlob = new Blob(chunks, { type: 'video/webm' })
    console.log(recordedBlob)
    // Create a download link and display it
    var downloadLink = document.createElement('a')
    downloadLink.href = URL.createObjectURL(recordedBlob)
    downloadLink.download = 'recorded-video.webm'
    document.body.appendChild(downloadLink)
    downloadLink.click()

    // Release resources
    URL.revokeObjectURL(recordedBlob)
    chunks = []
  }
  mediaRecorder.start()
}

/**
 * 停止录制
 */
const stopRecordVideo = () => {
  mediaRecorder.stop()
}
</script>

<template>
  <div class="chat-page">
    <div class="header">
      <div>ID: {{ peerId }}</div>
      <div style="display: flex">
        <div style="width: 200px; margin-left: 100px">
          <el-input v-model="remotePeerId" placeholder="远端peerId"></el-input>
        </div>
        <div style="margin-left: 10px">
          <el-button @click="sendCall" type="primary">连接远端</el-button>
          <el-button @click="closeCall" type="danger">断开连接</el-button>
          <el-button @click="startRecordVideo" type="primary">开启录制</el-button>
          <el-button @click="stopRecordVideo" type="primary">停止录制</el-button>
        </div>
      </div>
    </div>
    <div class="content">
      <div class="left">
        <video ref="localVideo" class="video-preview" autoplay></video>
        <div class="user-name">自己</div>
        <video ref="remoteVideo" class="video-preview" autoplay></video>
        <div class="user-name">远端</div>
      </div>
      <div class="center">
        <div class="message-list">
          <ul>
            <li
              :style="{ textAlign: item.type === 'self' ? 'right' : 'left' }"
              v-for="(item, index) in messageList"
              :key="index"
            >
              <span>{{ item.type === 'self' ? '自己' : '远端' }}：</span>
              {{ item.message }}
            </li>
          </ul>
        </div>
        <div class="chat-input">
          <el-input
            v-model="message"
            @keyup.enter="sendMessage('self')"
            placeholder="请输入内容"
          ></el-input>
          <el-button type="primary" :disabled="!message" @click="sendMessage('self')"
            >发送</el-button
          >
        </div>
      </div>
      <div class="right"></div>
    </div>
  </div>
</template>
<style lang="scss" scoped>
.chat-page {
  width: 100vw;
  height: 100vh;
  display: flex;
  flex-direction: column;
  .header {
    height: 40px;
    line-height: 40px;
    background-color: #444;
    padding: 0 5px;
    color: #fff;
    display: flex;
    justify-content: space-between;
    align-items: center;
  }
  .content {
    flex: 1;
    display: flex;
  }
  .left {
    width: 200px;
  }
  .center {
    flex: 1;
    display: flex;
    flex-direction: column;
    background-color: #eee;
    .message-list {
      flex: 1;
      height: 0;
      overflow-y: auto;
      li {
        padding: 5px;
      }
    }
    .chat-input {
      padding: 5px;
      display: flex;
      align-items: center;
    }
  }

  .video-preview {
    width: 200px;
    height: 150px;
    object-fit: contain;
    display: block;
  }
  .user-name {
    height: 20px;
    line-height: 20px;
    font-size: 12px;
    text-align: center;
    background-color: #ccc;
  }
}
</style>
